home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software of the Month Club 2000 October
/
Software of the Month - Ultimate Collection Shareware 277.iso
/
pc
/
PROGRAMS
/
UTILITY
/
WINLINUX
/
DATA1.CAB
/
sbin_-_Static_Binary_Files
/
IPFWADM-.{3E
< prev
next >
Wrap
Text File
|
1999-09-17
|
21KB
|
857 lines
#! /bin/bash
# This is a wrapper script to simulate ipfwadm 2.3a. It ain't pretty,
# but it should work (for valid commands). `-V' is translated to `-W'
# or ignored if a `-W' option is already there, but always warned
# about.
# Paul.Russell@rustcorp.com.au, Nov-1997.
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# Version: 1.0.1: Fixed -t (no longer de-hexizes).
#
# Version: 1.0.2: Fixed undocumented `-a masq'.
# Should be OK now with bash v1.
# If we can't find ip_fwnames, call /sbin/ipfwadm-2.3.0
#
# Version: 1.1: Fixed printing counts for accounting chains list.
# Fixed -A -z and -A -f cases to do all 3 acct. rules.
#
# Version: 1.1.1: Fixed syntax error by escaping ( and ).
#
if [ -n "$DEBUG_IPFWADM" ]; then IPCHAINS=print_ipchains;
else IPCHAINS=/sbin/ipchains;
fi
PROC_FIREWALL_NAMES="/proc/net/ip_fwnames"
SPECIAL_CHAIN="IpFwAdM!"
START_MARK=10000
barf()
{
echo "$@"
echo
echo If this command worked with the original ipfwadm 2.3, please
echo submit a bug report to \`ipchains@rustcorp.com\'. Note that you
echo now need to be root, even to list the chains \(complain to Alan Cox\).
echo
echo The best way to do this is to submit the output of \`$0 --version\',
echo the command used to obtain this error, any previous ipfwadm
echo commands, and the output of \`ipchains-save\'.
echo
echo Then try flushing all the rules \`ipchains -F; ipchains -X\',
echo setting the DEBUG_IPFWADM variable \`export DEBUG_IPFWADM=1\' or
echo \`setenv DEBUG_IPFWADM 1\' and rerunning the command\(s\) which
echo caused this error.
exit 1
}
print_ipchains()
{
echo ipchains "$@" 1>&2
/sbin/ipchains "$@"
}
setup_chains()
{
if [ `wc -l < $PROC_FIREWALL_NAMES` != 3 -a -z "$DEBUG_IPFWADM" ]
then
echo You cannot mix the \`ipfwadm\' wrapper with ipchains. 1>&2
echo You must delete all user chains and flush all built-in chains 1>&2
echo if you want to use the \`ipfwadm\' wrapper. 1>&2
exit 1
fi
$IPCHAINS -N acctin
$IPCHAINS -N acctout
$IPCHAINS -N acctboth
$IPCHAINS -N inp
$IPCHAINS -N out
$IPCHAINS -N fwd
# Let all fragments through like the old code used to.
$IPCHAINS -A input -f -j ACCEPT
$IPCHAINS -A output -f -j ACCEPT
$IPCHAINS -A forward -f -j ACCEPT
# Jump to accounting rules. Order of traversal of acct rules
# doesn't matter.
$IPCHAINS -A input -j acctin
$IPCHAINS -A input -j acctboth
$IPCHAINS -A output -j acctout
$IPCHAINS -A output -j acctboth
# Now go to `real' chains.
$IPCHAINS -A input -j inp
$IPCHAINS -A output -j out
$IPCHAINS -A forward -j fwd
# Create dummy chains to mark this as an ipfwadm-emulation firewall.
$IPCHAINS -N $SPECIAL_CHAIN
# Insert min and max mark values.
$IPCHAINS -A $SPECIAL_CHAIN -m $START_MARK
$IPCHAINS -A $SPECIAL_CHAIN -m $(($START_MARK + 1))
}
# SIGH. We use identical marks to indicate which rules are actually
# the same rule (to simulate multiple ports, and -y without -P tcp).
# We start the marks at 1,000,000, so we can insert before them or append
# after them.
# In the accounting chain, marks are unique between the three acct* chains,
# so we can tell ordering.
print_count()
{
count=$(($1))
if let $(($count > 99999))
then
cntkb=$((($count + 500) / 1000))
if let $((cntkb > 9999))
then
cntmb=$((($count + 500000) / 1000000))
printf "%4sM " $cntmb
else
printf "%4sK " $cntkb
fi
else
printf "%5s " $count
fi
}
dump_rule()
{
# ARGS: $LIST_VERBOSE $EXPAND_NUMBERS $BIDIR $SYN_NO_PROTO $SRCPORTS $DSTPTS
# $PCNT $BCNT $TARG $PROTO $FLAGS $TOSA $TOSX $IFNM $NUM $SRCIP $DSTIP $REDIR
# $PRINT_COUNTS
# The ipfwadm code looks like: (* = -e only)
# * * * * * * *
# pcnt bcnt kind proto bkyo TOSA TXOR IFNM IFADD SRC DST SPTs -> DPTs REDIR
if [ -n "$1" -o -n "${19}" ]
then
# Packet and byte counts.
if [ -n "$2" ]; then printf "%8u " $7; else print_count $7; fi
if [ -n "$2" ]; then printf "%8u " $8; else print_count $8; fi
fi
# Kind
case "$9" in
in) printf "%-3s " "$9" ;;
out) printf "%-3s " "$9" ;;
i/o) printf "%-3s " "$9" ;;
*) printf "%-5s " "$9" ;;
esac
# Proto
printf "%-5s" "${10}"
if [ -n "$1" ]
then
# Flags
if [ "$3" != 0 ]; then printf "b"; else printf "-"; fi
case "${11}" in
*!y*) printf "k-" ;;
*y*) printf "-y" ;;
*) printf "--" ;;
esac
case "${11}" in
*l*) printf "l " ;;
*) printf "- " ;;
esac
# TOS
printf "${12} ${13} "
# Interface name
printf "%-7.16s " "${14}"
# Interface address
if [ -n "${15}" ]; then printf "%-15s " 0.0.0.0;
else printf "%-15s " any;
fi
fi
# Source and dest.
printf "%-20s " "${16}"
printf "%-20s" "${17}"
# Source Ports.
if [ "${10}" != tcp -a "${10}" != udp -a "${10}" != icmp ]
then
echo " n/a"
return
fi
printf " "
printf "$5" | tr ' ' ','
if [ "${10}" = icmp ]
then
echo
return
fi
# Dest ports.
if [ "$5" != "n/a" ]
then
printf " -> "
printf "$6" | tr ' ' ','
fi
# redirect ports.
if [ "$9" = "acc/r" ]
then
printf " => %s" "${18}"
fi
echo
}
get_policy() # CHAIN
{
case "`ipchains -L $1 | head -1`" in
*ACCEPT*)
echo accept;;
*MASQ*)
echo accept/masquerade;;
*REJECT*)
echo reject;;
*DENY*)
echo deny;;
*)
barf "Unknown policy for \`$1' - `ipchains -L $1 2>&1`"
esac
}
list_chain() # $CHAIN $LIST_VERBOSE $NUMERIC $EXPAND_NUMBERS
{
# if (!(format & FMT_NOCOUNTS)) {
# if (format & FMT_KILOMEGA) {
# fprintf(fp, FMT("%5s ","%s "), "pkts");
# fprintf(fp, FMT("%5s ","%s "), "bytes");
# } else {
# fprintf(fp, FMT("%8s ","%s "), "pkts");
# fprintf(fp, FMT("%10s ","%s "), "bytes");
# }
# }
IS_ACCT=""
case "$1" in
acct*) IS_ACCT="Y";;
inp) printf "IP firewall input rules, default policy: "
get_policy input
;;
out) printf "IP firewall output rules, default policy: "
get_policy output
;;
fwd) printf "IP firewall forward rules, default policy: "
get_policy forward
;;
*) barf "Unknown chain for list_chain - \`$1'"
;;
esac
if [ -n "$2" -o -n "$IS_ACCT" ]
then
if [ -z "$4" ]
then
printf "%5s " pkts
printf "%5s " bytes
else
printf "%8s " pkts
printf "%10s " bytes
fi
fi
# if (!(format & FMT_NOKIND)) {
# if (chain == CHN_ACCT)
# fprintf(fp, FMT("%-3s ","%s "), "dir");
# else
# fprintf(fp, FMT("%-5s ","%s "), "type");
# }
case "$1" in
acct*) printf "%-3s " dir ;;
*) printf "%-5s " type ;;
esac
# fputs("prot ", fp);
printf "prot "
# if (format & FMT_OPTIONS)
# fputs("opt ", fp);
# if (format & FMT_TOS)
# fputs("tosa tosx ", fp);
# if (format & FMT_VIA) {
# fprintf(fp, FMT("%-7s ","(%s "), "ifname");
# fprintf(fp, FMT("%-15s ","%s) "), "ifaddress");
# }
if [ -n "$2" ]
then
printf "opt tosa tosx %-7s %-15s " ifname ifaddress
fi
# fprintf(fp, FMT("%-20s ","%s "), "source");
# fprintf(fp, FMT("%-20s ","%s "), "destination");
# fputs("ports\n", fp);
# }
printf "%-20s %-20s ports" source destination
echo
case "$1" in
acct*) shift;
(list_chain_real acctin "$@" "1" "1"
list_chain_real acctout "$@" "1" "1"
list_chain_real acctboth "$@" "1" "1") | sort -n | cut -c11-;;
*) list_chain_real "$@" ;;
esac
}
list_chain_real() # $CHAIN $LIST_VERBOSE $NUMERIC $EXPAND_NUMBERS $PRINT_COUNTS $PREPEND_MARK
{
CHAIN="$1"
LIST_VERBOSE="$2"
NUMERIC="$3"
EXPAND_NUMBERS="$4"
PRINT_COUNTS="$5"
PREPEND_MARK="$6"
# The ipfwadm code looks like: (* = -e only)
# * * * * * * *
# pcnt bcnt kind proto bkyo TOSA TXOR IFNM IFADD SRC DST SPTs -> DPTs REDIR
#
# The ipchains code looks like: (* = -v only)
# * * * * * * *
# pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR
LAST_MARK=xxx
BIDIR=0
SYN_NO_PROTO=0
SRCPORTS=""
DSTPORTS=""
[ -z "$NUMERIC" ] || NUMERIC="-n"
$IPCHAINS -L $CHAIN -v -x $NUMERIC | tail +3 |
while true
do
if ! read PCNT BCNT TARG PROTO FLAGS TOSA TOSX IFNM MARK SRCIP DSTIP SRCPTS IGN1 DSTPTS REDIR
then
# Dump last rule.
if [ "$LAST_MARK" != "xxx" ]
then
[ -z "$PREPEND_MARK" ] || printf "%-10s " "$LAST_MARK"
dump_rule "$LIST_VERBOSE" "$EXPAND_NUMBERS" $BIDIR $SYN_NO_PROTO "$SRCPORTS" "$DSTPORTS" $LAST_PCNT $LAST_BCNT $LAST_TARG $LAST_PROTO $LAST_FLAGS $LAST_TOSA $LAST_TOSX "$LAST_IFNM" "$NUMERIC" $LAST_SRCIP $LAST_DSTIP "$LAST_REDIR" "$PRINT_COUNTS"
fi
return
fi
[ -z "$DEBUG_IPFWADM" ] || echo RULE is "$PCNT $BCNT $TARG $PROTO $FLAGS $TOSA $TOSX "$IFNM" $MARK $SRCIP $DSTIP $SRCPTS $IGN1 $DSTPTS $REDIR" 1>&2
if [ "$LAST_MARK" = "$MARK" ]
then
# Fold rules back together.
# We combine for any of the following reasons:
# -k or -y used with no protocol: first rule has proto TCP and 'y'.
# -b used: SRC & DST reversed.
# Multiple ports: all the same but for port.
# Worst cases:
# ipfwadm -I -a accept -b -P tcp -S 0/0 1 4 -D 1/1 5 9
# => pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR
# ? ? ? TCP ? ? ? ? ? 0/0 1/1 1 5
# ? ? ? TCP ? ? ? ? ? 1/1 0/0 5 1
# ? ? ? TCP ? ? ? ? ? 0/0 1/1 1 9
# ? ? ? TCP ? ? ? ? ? 1/1 0/0 9 1
# ? ? ? TCP ? ? ? ? ? 0/0 1/1 4 5
# ? ? ? TCP ? ? ? ? ? 1/1 0/0 5 4
# ? ? ? TCP ? ? ? ? ? 0/0 1/1 4 9
# ? ? ? TCP ? ? ? ? ? 1/1 0/0 9 4
#
# ipfwadm -I -a accept -b -y -S 0/0 -D 1/1
# => pcnt bcnt targ proto !yfl TOSA TXOR IFNM MARK SRC DST SPTs -> DPTs REDIR
# ? ? ? TCP ?y?? ? ? ? ? 0/0 1/1
# ? ? ? TCP ?y?? ? ? ? ? 1/1 0/0
# ? ? ? ANY ?-?? ? ? ? ? 0/0 1/1
# ? ? ? ANY ?-?? ? ? ? ? 1/1 0/0
# if [ -n "$DEBUG_IPFWADM" ]
# then
# echo LAST_PROTO = \`"$LAST_PROTO"\'
# echo PROTO = \`"$PROTO"\'
# echo LAST_SRCIP = \`"$LAST_SRCIP"\'
# echo DSTIP = \`"$DSTIP"\'
# echo LAST_DSTIP = \`"$LAST_DSTIP"\'
# echo SRCIP = \`"$SRCIP"\'
# echo LAST_SRCPTS = \`"$LAST_SRCPTS"\'
# echo DSTPTS = \`"$DSTPTS"\'
# echo LAST_DSTPTS = \`"$LAST_DSTPTS"\'
# echo SRCPTS = \`"$SRCPTS"\'
# fi
if [ "$LAST_PROTO" = \!tcp -a "$PROTO" = tcp ]
then
[ -n "$DEBUG_IPFWADM" ] && echo "Found SYN rule."
SYN_NO_PROTO=1
PCNT=$(($LAST_PCNT + $PCNT))
BCNT=$(($LAST_BCNT + $BCNT))
PROTO="all"
elif [ "$LAST_SRCIP" = "$DSTIP" -a "$LAST_DSTIP" = "$SRCIP" -a "$LAST_SRCPTS" = "$DSTPTS" -a "$LAST_DSTPTS" = "$SRCPTS" ]
then
[ -n "$DEBUG_IPFWADM" ] && echo "Found bidir rule."
BIDIR=1
LAST_PCNT=$(($LAST_PCNT + $PCNT))
LAST_BCNT=$(($LAST_BCNT + $BCNT))
# Don't transfer this rule to LAST_ vars - effectively ignore.
continue;
else
[ -n "$DEBUG_IPFWADM" ] && echo "Found port rule."
# For n source ports and m dest ports, there will be
# n x m rules. So, we add to SRCPORTS when we see a new
# SRCPTS, but only add to DSTPORTS for the first SRCPORTS.
if [ "$SRCPTS" != "$LAST_SRCPTS" ]
then
SRCPORTS="$SRCPORTS $SRCPTS"
fi
if [ "$SRCPORTS" = "$SRCPTS" ]
then
DSTPORTS="$DSTPORTS $DSTPTS"
fi
PCNT=$(($LAST_PCNT + $PCNT))
BCNT=$(($LAST_BCNT + $BCNT))
fi
else
# Dump last rule.
if [ "$LAST_MARK" != "xxx" ]
then
[ -z "$PREPEND_MARK" ] || printf "%-10s " "$LAST_MARK"
dump_rule "$LIST_VERBOSE" "$EXPAND_NUMBERS" $BIDIR $SYN_NO_PROTO "$SRCPORTS" "$DSTPORTS" $LAST_PCNT $LAST_BCNT $LAST_TARG $LAST_PROTO $LAST_FLAGS $LAST_TOSA $LAST_TOSX "$LAST_IFNM" "$NUMERIC" $LAST_SRCIP $LAST_DSTIP "$LAST_REDIR" "$PRINT_COUNTS"
fi
BIDIR=0
SYN_NO_PROTO=0
SRCPORTS="$SRCPTS"
DSTPORTS="$DSTPTS"
fi
# Save for next iteration, in case mark the same.
LAST_PCNT=$PCNT
LAST_BCNT=$BCNT
LAST_PROTO=$PROTO
LAST_FLAGS=$FLAGS
LAST_TOSA=$TOSA
LAST_TOSX=$TOSX
LAST_IFNM="$IFNM"
LAST_MARK=$MARK
LAST_SRCIP=$SRCIP
LAST_DSTIP=$DSTIP
LAST_REDIR="$REDIR"
LAST_SRCPTS="$SRCPTS"
LAST_DSTPTS="$DSTPTS"
case "$CHAIN" in
acctin) LAST_TARG=in ;;
acctout) LAST_TARG=out ;;
acctboth) LAST_TART=i/o ;;
*)
case "$TARG" in
REDIRECT) LAST_TARG="acc/r" ;;
MASQ) LAST_TARG="acc/m" ;;
ACCEPT) LAST_TARG="acc" ;;
REJECT) LAST_TARG="rej" ;;
DENY) LAST_TARG="deny" ;;
*) barf Unknown target \`"$TARG"\'. ;;
esac
;;
esac
done
}
############################################################################
if [ ! -f $PROC_FIREWALL_NAMES ]
then
if [ -f /proc/net/ip_input -a -x /sbin/ipfwadm-2.3.0 ]
then
# Old kernel. Let's play nice.
exec /sbin/ipfwadm-2.3.0 "$@"
fi
echo "Generic IP Firewall Chains not in this kernel" 1>&2
exit 1
fi
while [ $# != 0 ]
do
case "$1" in
-A)
case x"$2" in
x-*) CHAIN=acctboth ;;
xboth) CHAIN=acctboth; shift ;;
xin) CHAIN=acctin; shift ;;
xout) CHAIN=acctout; shift ;;
x) CHAIN=acctboth ;;
*) barf Unknown option \`"$2"\' ;;
esac
;;
-I)
CHAIN=inp
;;
-O)
CHAIN=out
;;
-F)
CHAIN=fwd
;;
-M)
MASQ_MODE=1
;;
-a)
COMMAND=-A
case x"$2" in
x-*) TARGET="" ;;
x) TARGET="" ;;
xr*) TARGET=REJECT; shift ;;
xd*) TARGET=DENY; shift ;;
xa*) TARGET=ACCEPT; shift ;;
xm*) TARGET=ACCEPT; MASQ=1; shift ;;
*) barf Unknown policy for append: \`"$2"\' ;;
esac
;;
-i)
COMMAND="-I "
case x"$2" in
x-*) TARGET="" ;;
x) TARGET="" ;;
xr*) TARGET=REJECT; shift ;;
xd*) TARGET=DENY; shift ;;
xa*) TARGET=ACCEPT; shift ;;
*) barf Unknown policy for insert: \`"$2"\' ;;
esac
;;
-d)
COMMAND=-D
case x"$2" in
x-*) TARGET="" ;;
x) TARGET="" ;;
xr*) TARGET=REJECT; shift ;;
xd*) TARGET=DENY; shift ;;
xa*) TARGET=ACCEPT; shift ;;
*) barf Unknown policy for delete: \`"$2"\' ;;
esac
;;
-l)
LIST=1
;;
-z)
COMMAND=-Z
;;
-f)
COMMAND=-F
;;
-p)
COMMAND=-P
case "$2" in
r*) TARGET=REJECT; shift ;;
d*) TARGET=DENY; shift ;;
a*) TARGET=ACCEPT; shift ;;
*) barf Unknown policy for -p: \`"$2"\' ;;
esac
;;
-s)
COMMAND=-S
OPTIONS="$2 $3 $4"
shift 3
;;
-c)
COMMAND=-C
;;
-h)
print_help
;;
-P)
PROTOCOL="-p $2"
shift
;;
-S)
SRC_OPTIONS="-s $2"
shift
while true
do
case x"$2" in
x) break ;;
x-*) break ;;
x?*) SRC_PORTS="$2 $SRC_PORTS" ;;
esac
shift
done
;;
-D)
DST_OPTIONS="-d $2"
shift
while true
do
case x"$2" in
x) break ;;
x-*) break ;;
x?*) DST_PORTS="$2 $DST_PORTS" ;;
esac
shift
done
;;
-V)
VIA_ADDR="$2"
shift
;;
-W)
INTERFACE="$2"
OPTIONS="$OPTIONS -i $2"
shift
;;
-b)
OPTIONS="$OPTIONS -b"
;;
-e)
LIST_VERBOSE=1
;;
-k)
TCPSYN="! -y"
;;
-m)
MASQ=1
;;
-n)
NUMERIC=1
;;
-o)
OPTIONS="$OPTIONS -l"
;;
-r)
case x"$2" in
x-*) REDIR=0 ;;
x) REDIR=0 ;;
x?*) REDIR="$2"; shift ;;
esac
;;
-t)
TOSAND=$(($2 | 0x01))
TOSXOR=$(($3 & 0xFE))
OPTIONS="$OPTIONS -t "`printf "0x%02x 0x%02x" $TOSAND $TOSXOR`
shift 2
;;
-v)
OPTIONS="$OPTIONS -v"
;;
-x)
EXPAND_NUMBERS=1;
;;
-y)
TCPSYN="-y"
;;
--version)
echo "ipfwadm wrapper version 1.1"
exit 0
;;
*) barf Unexpected argument \`"$1"\'.
;;
esac
shift
done
# Variables to worry about:
# $CHAIN - actual chain to work on.
# X$MASQ_MODE - set if -M given.
# X$COMMAND - set if this is a simple command conversion.
# X$TARGET - set for COMMAND of -A, -I, -D or -P (but see REDIR and MASQ).
# X$LIST - set if they want a list.
# X$NUMERIC - list with -n.
# X$LIST_VERBOSE - list all info.
# X$EXPAND_NUMBERS - list full numbers.
# X$OPTIONS - miscellaneous easy-to-convert options.
# X$SRC_OPTIONS - set if a source address is specified.
# X$SRC_PORTS - space-separated list of specified source ports/ranges.
# X$DST_OPTIONS - set if a dest address is specified.
# X$DST_PORTS - space-separated list of specified dest ports/ranges.
# $VIA_ADDR - an interface address if one is specified.
# $INTERFACE - an interface name if one is specified.
# X$TCPSYN - set if `-k' or `-y' is specified.
# X$MASQ - set if `-m' is specified.
# X$REDIR - set to the port if `-r port' is specified
if [ -n "$MASQ_MODE" ]
then
if [ -n "$LIST" ]
then
$IPCHAINS -M -L $OPTIONS
else
$IPCHAINS $COMMAND $OPTIONS
fi
elif [ -n "$LIST" ]
then
if ! grep -q IpFwAdM! < $PROC_FIREWALL_NAMES
then
echo "Chains are empty. (ie. ipfwadm has not been used on them)." 1>&2
exit 0
fi
# Construct a list.
if [ x$COMMAND = x-Z ]
then
# We have to atomically zero and list a chain. This is
# currently impossible, so we:
# 1) stop all packets on the given chain.
# 2) list the values.
# 3) clear the counters.
# 4) resume on the given chain.
case "$CHAIN" in
acct*)
$IPCHAINS -I 1 input -j DENY
$IPCHAINS -I 1 output -j DENY
;;
inp)
$IPCHAINS -I 1 input -j DENY
;;
out)
$IPCHAINS -I 1 output -j DENY
;;
fwd)
$IPCHAINS -I 1 forward -j DENY
;;
*) barf Unknown chain to stop: \`"$CHAIN"\'.
esac
list_chain $CHAIN "$LIST_VERBOSE" "$NUMERIC" "$EXPAND_NUMBERS"
$IPFWADM -Z $CHAIN
case "$CHAIN" in
acct*)
$IPCHAINS -D 1 input
$IPCHAINS -D 1 output
;;
inp)
$IPCHAINS -D 1 input
;;
out)
$IPCHAINS -D 1 output
;;
fwd)
$IPCHAINS -D 1 forward
;;
*) barf Unknown chain to restart: \`"$CHAIN"\'.
esac
else
list_chain $CHAIN "$LIST_VERBOSE" "$NUMERIC" "$EXPAND_NUMBERS"
fi
elif [ x"$COMMAND" = x"-F" -o x"$COMMAND" = x"-Z" -o x"$COMMAND" = x"-C" ]
then
if ! grep -q IpFwAdM! < $PROC_FIREWALL_NAMES
then
echo "Chains are empty. (ie. ipfwadm has not been used on them)." 1>&2
exit 0
fi
if [ "$CHAIN" = acctboth ]
then
# Do it to all of them.
$IPCHAINS $COMMAND acctin $OPTIONS
$IPCHAINS $COMMAND acctout $OPTIONS
fi
$IPCHAINS $COMMAND $CHAIN $OPTIONS
else
grep -q IpFwAdM! < $PROC_FIREWALL_NAMES || setup_chains
# Figure out what the target should be.
if [ -n "$REDIR" ]
then
TARGET=REDIRECT
elif [ -n "$MASQ" ]
then
TARGET=MASQ
fi
if [ x"$COMMAND" = x"-P" ]
then
case "$CHAIN" in
inp) CHAIN=input ;;
out) CHAIN=output ;;
fwd) CHAIN=forward ;;
*) barf "Illegal chain for -P: \`$CHAIN'" ;;
esac
$IPCHAINS $COMMAND $CHAIN $TARGET $OPTIONS
else
# If they used -V, and not -W, then try to figure out interface
# name. ALWAYS warn about difference.
if [ -n "$VIA_ADDR" ]
then
if [ -n "$INTERFACE" ]
then
echo Warning: \`-V $VIA_ADDR\' option ignored\; using \`-W $INTERFACE\' only.
else
INTERFACE=`ifconfig | awk -v ADDR=$VIA_ADDR '/^[a-z0-9A-Z]/ { IFNAME=$1 } $0 ~ "^[^A-Za-z0-9:]*inet addr:" ADDR { print IFNAME}'`
if [ -z "$INTERFACE" ]
then
echo Can\'t handle -V option: can\'t find interface name for the address \`$VIA_ADDR\'. 1>&2
echo Please replace the -V with the appropriate -W option. 1>&2
exit 1
fi
echo Replacing \`-V $VIA_ADDR\' with \`-W $INTERFACE\'.
OPTIONS="$OPTIONS -i $INTERFACE"
fi
fi
# Insert, append or delete.
case $COMMAND in
# For Insert, get (and decrement) minimal mark #.
-I*) MARK=$(set $($IPCHAINS -L $SPECIAL_CHAIN -v | head -3 | tail -1); echo $9)
$IPCHAINS -R $SPECIAL_CHAIN 1 -m $(($MARK - 1))
MARK="-m $MARK"
;;
# For Append, get (and increment) maximum mark #.
-A) MARK=$(set $($IPCHAINS -L $SPECIAL_CHAIN -v | head -4 | tail -1); echo $9)
$IPCHAINS -R $SPECIAL_CHAIN 2 -m $(($MARK + 1))
MARK="-m $MARK"
;;
esac
# Only care about TCP SYN if -p TCP not specified.
if [ -n "$TCPSYN" ]
then
case "$PROTOCOL" in
*[Tt][Cc][Pp])
OPTIONS="$OPTIONS $PROTOCOL $TCPSYN"
TCPSYN=""
;;
esac
else
OPTIONS="$OPTIONS $PROTOCOL"
fi
# Mangle source port and dest port args.
if [ -z "$SRC_PORTS" ]; then SRC_PORTS="X"; fi
if [ -z "$DST_PORTS" ]; then DST_PORTS="X"; fi
[ -n "$TARGET" ] && TARGET="-j $TARGET"
for SRC in $SRC_PORTS
do
if [ $SRC = "X" ]; then SRC=""; fi
for DST in $DST_PORTS
do
if [ $DST = "X" ]; then DST=""; fi
if [ -n "$TCPSYN" ]
then
$IPCHAINS $COMMAND $CHAIN $SRC $DST $OPTIONS -p ! tcp $TARGET $MARK || barf "ipchains failed!"
$IPCHAINS $COMMAND $CHAIN $SRC $DST $OPTIONS -p tcp $TCPSYN $TARGET $MARK || barf "ipchains failed!"
else
$IPCHAINS $COMMAND $CHAIN $SRC_OPTIONS $SRC $DST_OPTIONS $DST $OPTIONS $TARGET $MARK
fi
done
done
fi
fi